#ifndef _AT24C04_H_
#define _AT24C04_H_

#include "stdint.h"

#ifdef __cplusplus
extern "C"
{
#endif

#define AT24C02 0
#define AT24C04 0
#define AT24C16 0
#define AT24C32 1
#define AT24C64 0
#define AT24C256 0

#if AT24C02 > 0
#define EEP_PAGE_SIZE 8
#define EEP_PAGE_MASK 0x07 
#define EEP_ADDR_SIZE 0x100
#define EEP_SUBA_SIZE 0x100
#define EEP_SUBA_MASK 0xFF
#define EEP_ADDR_TYPE 0 

#elif AT24C04 > 0
#define EEP_PAGE_SIZE 16
#define EEP_PAGE_MASK 0x0F 
#define EEP_ADDR_SIZE 0x200
#define EEP_SUBA_SIZE 0x100
#define EEP_SUBA_MASK 0xFF
#define EEP_ADDR_TYPE 2 

#elif AT24C16 > 0
#define EEP_PAGE_SIZE 16
#define EEP_PAGE_MASK 0x0F 
#define EEP_ADDR_SIZE 0x800
#define EEP_SUBA_SIZE 0x100
#define EEP_SUBA_MASK 0xFF
#define EEP_ADDR_TYPE 0x0E 

#elif AT24C32 > 0
#define EEP_PAGE_SIZE 32
#define EEP_PAGE_MASK 0x1F 
#define EEP_ADDR_SIZE 0x1000
#define EEP_SUBA_SIZE 0x1000
#define EEP_SUBA_MASK 0x0FFF
#define EEP_ADDR_TYPE 0x01 

#elif AT24C64 > 0
#define EEP_PAGE_SIZE 32
#define EEP_PAGE_MASK 0x1F 
#define EEP_ADDR_SIZE 0x2000
#define EEP_SUBA_SIZE 0x2000
#define EEP_SUBA_MASK 0x1FFF
#define EEP_ADDR_TYPE 0x01 

#elif AT24C256 > 0
#define EEP_PAGE_SIZE 64
#define EEP_PAGE_MASK 0x3F 
#define EEP_ADDR_SIZE 0x8000
#define EEP_SUBA_SIZE 0x8000
#define EEP_SUBA_MASK 0x7FFF
#define EEP_ADDR_TYPE 1 
#else
#error AT24 SEL ERROR
#endif

#define EEP_CHIP_ADDR 0xA0 

	typedef const struct
	{
		uint8_t CHIP_ADDR;
		uint8_t ADDR_TYPE;
		uint16_t PAGE_SIZE;
		uint16_t PAGE_MASK;
		uint16_t ADDR_SIZE;
		uint16_t SUBA_SIZE;
		uint16_t SUBA_MASK;
	} at24c_cfg_type;

	uint8_t at24_write(uint16_t DataAdd, uint16_t Len, uint8_t *Rsc);
	uint8_t at24_read(uint16_t DataAdd, uint16_t Len, uint8_t *Des);

	typedef const struct
	{
		uint8_t CHIP_ADDR;
		uint8_t ADDR_TYPE;
		uint16_t PAGE_SIZE;
		uint16_t PAGE_MASK;
		uint16_t ADDR_SIZE;
		uint16_t SUBA_SIZE;
		uint16_t SUBA_MASK;

		void (*at_iic_start)(void);
		void (*at_iic_stop)(void);
		uint8_t (*at_iic_snd_byte)(uint8_t data); 
		uint8_t (*at_iic_rcv_byte)(void);
		void (*at_iic_ack)(uint8_t);
	} at24c_multi_cfg_type;

	uint8_t at24_multi_write(at24c_multi_cfg_type *at24c, uint16_t DataAdd, uint16_t Len, uint8_t *Rsc);
	uint8_t at24_multi_read(at24c_multi_cfg_type *at24c, uint16_t DataAdd, uint16_t Len, uint8_t *Des);

#ifdef __cplusplus
}
#endif

#endif
